import datetime

import numpy as np
import pandas as pd
from dateutil.relativedelta import relativedelta

res = pd.read_csv("history_Index_k_data.csv")
date_list = np.array(res['date'])
# print(res)
count_knockIn = 0
# 敲入列表
count_knockIn_snows = []
# 敲出列表
count_knockOut_snows = []
count_knockOut = 0
snow_opts = []
date_format = '%Y-%m-%d'
init_notional = 10000
incomeRate_month = 0.06
total_income = 0
total_income_正 = 0
knock_in_buy_date = []

knock_in_dates = set()
def to_date_str(date):
    return date.strftime(date_format)

for row in res.itertuples():
    # print(type(row))
    spot = row.close
    date = row.date
    dateTime = datetime.datetime.strptime(date, date_format)

    snow_opt = {"start": datetime.datetime.strptime(row.date, date_format)}
    snow_opt.update({"end": (snow_opt.get('start') + relativedelta(years=2))})
    snow_opt.update({"current": row.close})
    # 低于75% 为敲入线
    snow_opt.update({"knockInSpot": row.close * 0.75})
    snow_opt.update({"knockOutSpot": row.close * 1})
    snow_opt.update({"flag": False})

    # 观察列表，每月观察
    observations = []
    after_month = dateTime
    for i in range(24):
        observer = dateTime + relativedelta(months=i + 1)
        observer_str = observer.strftime(date_format)

        while observer_str not in date_list:
            # 未来日期过滤
            if observer >= datetime.datetime.now():
                break
            observer = observer + relativedelta(days=1)
            observer_str = observer.strftime(date_format)
        observations.append(observer_str)
    snow_opt.update({"observations": observations})
    snow_opts.append(snow_opt)

    for snow in snow_opts:
        if snow.get("flag") is False:
            # 到期
            if datetime.datetime.strptime(date, date_format) >= snow.get("end"):
                snow.update({'flag': True})
                print("雪球%s,到期未敲出未敲入" % snow.get("start"))
                settle = init_notional * incomeRate_month * 24
                total_income += settle
                total_income_正 += settle
            elif date in snow.get("observations") and snow.get("knockOutSpot") <= spot:
                count_knockOut += 1
                snow.update({'flag': True})
                count_knockOut_snows.append(
                    {
                        "knockInDate": date,
                        "spot": spot,
                        "snow_knock_out": snow.get("knockOutSpot"),
                        "index": snow
                    }
                )
                print("雪球%s,第%s个月敲出,敲出日期%s" % (
                    snow.get("start"), snow.get("observations").index(date) + 1, date))
                settle = init_notional * incomeRate_month * (
                        snow.get("observations").index(date) + 1)
                total_income += settle
                total_income_正 += settle
            elif snow.get("knockInSpot") >= spot:
                snow.update({'flag': True})
                count_knockIn += 1
                count_knockIn_snows.append(
                    {
                        "knockInDate": date,
                        "spot": spot,
                        "snow_knock_in": snow.get("knockInSpot"),
                        "index": snow
                    }
                )
                knock_in_buy_date.append(to_date_str(snow.get("start")))
                print("雪球%s,敲入日期%s" % (snow.get("start"), date))
                knock_in_dates.add(date)
                total_income -= init_notional

print("总共%d笔,敲入次数:%d,敲出次数:%d" % (len(snow_opts), count_knockIn, count_knockOut))
print("敲出概率:%f6" % (count_knockOut / (count_knockIn + count_knockOut)))
print("敲入概率:%f6" % (count_knockIn / (count_knockIn + count_knockOut)))
print("敲入日期：%s" % knock_in_dates)
print("买入日期，并且敲入, %s" % knock_in_buy_date)

print('理论结算金额: %s' % total_income)
print('理论结算总赚金额: %s' % total_income_正)


total_notional = (count_knockIn + count_knockOut) * init_notional
income_rate = total_income / total_notional
print("总投入%f 万元,总收益率 %f" % (total_notional/ 10000 , income_rate))
